package com.example.dingtalklogin.adpter.dingtalk;

import com.example.dingtalklogin.common.util.UserUtil;
import com.example.dingtalklogin.manager.dingtalk.*;
import com.example.dingtalklogin.manager.dingtalk.DingtalkOApiClient;
import com.example.dingtalklogin.service.DingtalkService;
import com.example.dingtalklogin.service.dto.DingtalkBindingCmd;
import com.example.dingtalklogin.service.dto.DingtalkLoginCmd;
import com.example.dingtalklogin.service.dto.data.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

@RequestMapping("/dingtalk")
@Controller
@Slf4j
public class DingtalkController {

    @Resource
    private DingtalkService dingtalkService;
    @Resource
    private DingtalkApiClient dingtalkApiClient;
    @Resource
    private AccessTokenManager accessTokenManager;
    @Resource
    private DingtalkOApiClient dingtalkOApiClient;

    /**
     * 免登地址view页面
     * @return
     */
    @GetMapping("/exempt/view")
    public ModelAndView exemptLoginView(){
        ModelAndView mav = new ModelAndView("exempt");
        return mav;
    }

    /**
     * 免登地址
     * @param authCode
     * @return
     */
    @GetMapping("/exempt")
    public ModelAndView exemptLogin(@RequestParam String authCode){

        ExemptUserInfoRequest request = new ExemptUserInfoRequest();
        request.setCode(authCode);

        OApiResponse<ExemptUserInfo> userInfo = dingtalkOApiClient.getExemptUserInfo(request);
        DingtalkLoginCmd cmd = new DingtalkLoginCmd();
        cmd.setUnionId(userInfo.getResult().getUnionId());
        UserDto loginUser = dingtalkService.login(cmd);
        // 保存登录状态
        UserUtil.setCurrUser(loginUser);
        ModelAndView mav = new ModelAndView("redirect:/");
        return mav;
    }

    /**
     * 钉钉认证回调
     *  - 登录
     *  - 绑定
     * @param authCode
     * @return
     * @throws Exception
     */
    @GetMapping("/auth")
    public ModelAndView auth(@RequestParam String authCode
            , @RequestParam String state) {
        switch (state){
            // 登录逻辑
            case "LOGIN":
                login(authCode);
                break;
            // 绑定逻辑
            case "BINDING":
                binding(authCode);
                break;
            default:
                log.warn("authCode: {} state: {} 无效的操作！！", authCode, state);
                break;
        }
        return new ModelAndView("redirect:/");
    }

    private void login(String authCode){
        UserTokenResponse userToken = accessTokenManager.getUserToken(authCode);
        UserInfoResponse userInfo = dingtalkApiClient.getUserInfo("me", userToken.getAccessToken());
        DingtalkLoginCmd cmd = new DingtalkLoginCmd();
        cmd.setUnionId(userInfo.getUnionId());

        UserDto loginUser = dingtalkService.login(cmd);
        // 保存登录状态
        UserUtil.setCurrUser(loginUser);
    }

    private void binding(String authCode){
        UserTokenResponse userToken = accessTokenManager.getUserToken(authCode);
        UserInfoResponse userInfo = dingtalkApiClient.getUserInfo("me", userToken.getAccessToken());
        DingtalkBindingCmd cmd = new DingtalkBindingCmd();
        UserDto userDto = UserUtil.getCurrUser();
        cmd.setUserId(userDto.getId());
        cmd.setOpUserId(userDto.getId());
        cmd.setUnionId(userInfo.getUnionId());
        dingtalkService.binding(cmd);
        // 清除登录状态重新登录
        UserUtil.setCurrUser(null);
    }
}
